from django.db import models
from django.db.models import Q
from django.conf import settings
from django.utils import timezone
from django.contrib.auth import get_user_model
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.contrib.postgres.fields import ArrayField

from ..permissions.choice import MEMBERS_PERMISSIONS
from .services import get_project_report_file_path
from .services import get_project_logo_file_path
from .services import get_project_map_file_path
from .equipments.models import UAV, Camera
from .utils.choices import ANALYSIS_STATUS
from .utils.choices import IMAGE_STATUS
from .utils.choices import VIEW_STATUS


class Role(models.Model):
    """
    角色表
    """
    name = models.CharField(max_length=200, null=False, blank=False, verbose_name=_("name"))

    "代称，角色（slugField变小写并加上-）"
    slug = models.SlugField(max_length=250, null=True, blank=True, verbose_name=_("slug"))

    "拥有权限"
    permissions = models.TextField(null=True, blank=False, verbose_name=_("permissions"))

    "次序"
    order = models.IntegerField(default=10, null=True, blank=False, verbose_name=_("order"))

    "关联的项目"
    project = models.ForeignKey("projects.Project", null=True, blank=False,
                                related_name="roles", verbose_name=_("project"),
                                on_delete=models.CASCADE)

    class Meta:
        verbose_name = "role"
        verbose_name_plural = "roles"
        ordering = ["order", "slug"]
        unique_together = (("slug", "project"),)

    def __str__(self):
        return self.name


class Membership(models.Model):
    """
    团队表
    """
    "用户"
    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, default=None, related_name="memberships",
                             on_delete=models.CASCADE)
    "项目"
    project = models.ForeignKey("projects.Project", null=False, blank=False, related_name="memberships",
                                on_delete=models.CASCADE)
    "角色"
    role = models.ForeignKey(Role, null=False, blank=False, related_name="memberships", on_delete=models.CASCADE)
    "管理员"
    is_admin = models.BooleanField(default=False, null=False, blank=False)
    "创建时间"
    created_date = models.DateTimeField(default=timezone.now, verbose_name=_("create date"))

    class Meta:
        verbose_name = "membership"
        verbose_name_plural = "memberships"
        unique_together = ("user", "project",)
        ordering = ["project", "user__full_name", "user__username", "user__email"]

    def get_user_project_membership(self, project, user):
        """
        判断是否是项目成员
        """
        try:
            membership = Membership.objects.get(project=project, user=user)
        except Exception as e:
            return (None, False)
        else:
            return (membership, True)


class ProjectDetail(models.Model):
    """
    项目详细
    """
    "项目公司"
    company = models.CharField(max_length=128, null=False, blank=True, verbose_name=_("company"))
    "项目位置"
    location = models.CharField(max_length=128, null=True, blank=True, verbose_name=_("location"))
    "运营时间"
    operation_date = models.DateTimeField(verbose_name=_("operation date"))
    "拍摄开始时间"
    start_date = models.DateTimeField(null=True, blank=True, verbose_name=_("start date"))
    "拍摄结束时间"
    end_date = models.DateTimeField(null=True, blank=True, verbose_name=_("end date"))
    "飞行架次"
    sorties = models.PositiveIntegerField(verbose_name=_("fly sorties"), default=0)
    "飞行时长"
    fly_time = models.CharField(max_length=32, null=True, blank=False, verbose_name=_("fly time"), default="0")
    "天气情况"
    weather = models.TextField(verbose_name=_("weather"))
    "无人机"
    uav = models.ForeignKey(UAV, related_name="uav", verbose_name=_("uav"), null=True, blank=True,
                            on_delete=models.CASCADE)
    "相机"
    camera = models.ForeignKey(Camera, related_name="camera", verbose_name=_("camera"), null=True, blank=True,
                               on_delete=models.CASCADE)

    class Meta:
        abstract = True


class ProjectStatus(models.Model):
    """
    项目状态
    """
    "图片状态"
    image_status = models.CharField(max_length=16, null=False, blank=False, choices=IMAGE_STATUS, default="0",
                                    verbose_name=_("image status"))
    "分析状态"
    analysis_status = models.CharField(max_length=16, null=False, blank=False, choices=ANALYSIS_STATUS,
                                       default="0", verbose_name=_("analysis status"))
    "查看状态"
    view_status = models.CharField(max_length=16, null=False, blank=False, choices=VIEW_STATUS,
                                   default="0", verbose_name=_("view status"))
    "分析进度"
    analysis_progress = models.FloatField(default=0, verbose_name=_("analysis progress"))

    class Meta:
        abstract = True


class ProjectType(models.Model):
    """
    项目类型表
    """
    name = models.CharField(max_length=8, null=False, blank=False, default="0", verbose_name=_("name"))
    description = models.TextField(null=True, blank=False, verbose_name=_("description"))


class Project(ProjectDetail, ProjectStatus):
    """
    项目表
    """
    "项目名"
    name = models.CharField(max_length=250, unique=True, null=False, blank=False, verbose_name=_("name"))
    "代称"
    slug = models.SlugField(max_length=250, null=True, blank=True, verbose_name=_("slug"))
    "描述"
    description = models.TextField(null=True, blank=False, verbose_name=_("description"))
    "logo"
    logo = models.FileField(upload_to=get_project_logo_file_path, max_length=500, null=True, blank=True,
                            verbose_name=_("logo"))
    "拥有者"
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name="owned_projects",
                              verbose_name=_("owner"), on_delete=models.CASCADE)
    "团队"
    members = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="projects", through="Membership",
                                     verbose_name=_("members"), through_fields=("project", "user"))
    "创建时间"
    created_date = models.DateTimeField(null=False, blank=False, verbose_name=_("created date"), default=timezone.now)

    "光伏报告"
    report_path = models.FileField(upload_to=get_project_report_file_path, max_length=500, null=True, blank=True,
                                   verbose_name=_("report"))
    "光伏地图"
    map_path = models.FileField(upload_to=get_project_map_file_path, max_length=500, null=True, blank=True,
                                verbose_name=_("map"))
    project_type = models.ForeignKey(ProjectType, related_name="project_type", verbose_name=_("project type"),
                                     null=True, blank=True, on_delete=models.CASCADE)

    class Meta:
        verbose_name = "项目"
        verbose_name_plural = "项目"
        ordering = ["created_date"]
        index_together = [["name"]]

    def __str__(self):
        return self.name

    def get_roles(self):
        return self.roles.all()

    def get_users(self, with_admin_privileges=None):
        user_model = get_user_model()
        members = self.memberships.all()
        if with_admin_privileges is not None:
            members = members.filter(Q(is_admin=True) | Q(user__id=self.owner.id))
        members = members.values_list("user", flat=True)
        return user_model.objects.filter(id__in=list(members))

    @cached_property
    def cached_memberships(self):
        return {m.user.id: m for m in
                self.memberships.exclude(user__isnull=True).select_related("user", "project", "role")}

    def cached_memberships_for_user(self, user):
        return self.cached_memberships.get(user.id, None)
